import common.Config
import common.Direction
import common.doDirectionAction
import common.filterAndForEach
import javafx.event.EventType
import javafx.scene.input.KeyCode
import javafx.scene.input.KeyEvent
import model.*
import model.inter.*
import org.itheima.kotlin.game.core.Window
import java.io.File
import java.util.concurrent.CopyOnWriteArrayList

class GameWindow:Window(title = "坦克大战",width = Config.DEFAULT_WINDOW_WIDTH,height = Config.DEFAULT_WINDOW_HEIGHT) {



    private val mAllView=CopyOnWriteArrayList<View>();

    lateinit var myTank: MyTank;

    /**
     * 做一些初始化的一些操作；
     */
    override fun onCreate() {

        println("onCreate")

        loadmap()
        loadMyTank()
        loadCamp();
    }

    /**
     * 这里我们加载营地；
     */
    private fun loadCamp() {

        var camp = Camp()
        camp.setPostion(5.5.toDouble(),11.5.toDouble())
        mAllView.add(camp)
    }

    private fun loadMyTank() {
        myTank = MyTank()
        myTank.setPostion(8, 12);
        mAllView.add(myTank)
    }

    private fun loadmap() {
        //这里我们要加载地图的一个操作；
        var file = File("/Users/mawenhao/ideaProjects/kotlinGame/TankGame/src/main/resources/map/1.map")

        var volIndex = 0;

        file.forEachLine {


            println("map: $it")

            it.split("")
                    .filter { !it.isNullOrEmpty() }
                    .forEachIndexed { colIndex, value ->

                        val view = when (value) {
                            "砖" -> {
                                Wall(); }
                            "水" -> {
                                Water()
                            }
                            "铁" -> {
                                SteelWall()
                            }
                            "草" -> {
                                Grass()
                            }
                            "敌" -> {
                                Enemy()
                            }
                            else -> {
                                //这里表示空白不管操作；
                                null
                            }
                        }

                        view?.run {
                            setPostion(colIndex, volIndex)
                            mAllView.add(this)
                            println("colIndex: $colIndex  volIndex:$volIndex")
                        }

                    }

            volIndex++;
        }
    }

    /**
     * 画地图
     */
    override fun onDisplay() {

        println("onDisplay：mViewsSize(): ${mAllView.size}")
        //1.将相应的的View 绘制到屏幕上；
        mAllView.forEach {
                it.draw()
        }
    }

    /**
     * 处理按键的方法
     */
    override fun onKeyPressed(event: KeyEvent) {


        println("onKeyPressed")

        var direction = when (event.code) {
            KeyCode.UP -> Direction.UP
            KeyCode.DOWN -> Direction.DOWN
            KeyCode.LEFT -> Direction.LEFT
            KeyCode.RIGHT -> Direction.RIGHT
            KeyCode.SPACE->{

                //这里我们要做的一个操作就是发射一颗子弹
                val bullet:Bullet=myTank.createBullet();
                mAllView.add(bullet)
                null
            }
            else -> {
                null
            }
        }

        if (direction != null) {

            myTank.move(direction)

        }

        //处理碰撞这块还是没有处理好，看看视频能有什么好的办法；
        //这里我们处理tank的方向的话的，
        // 存在一个问题就是tank自动和子弹发生了碰撞这样，只要一发射子弹就不能走了
        //所以这里我们要我们要换一种思路解决这个问题；
        //这里之所以存在这个问题是因为，我们每次案件的时候去检测是否发生了冲突，这样可以，但是不太好，
        //为什么这样说能呢？比如地方tank呢，我们该怎么处理呢？
        //所以这里不妨，修改一下实现思路；
      /*
           if (direction != null) {

                myTank.changeDirection(direction)

                var willHitDirection:Direction?=null;
                //这里我们要跳出去；
                run outside@{
                    mAllView.forEach {

                        //这里我们要遍历所有的View,
                        // 检查是否所有的都没有和Tank发生碰撞，
                        // 如果是的话，我们要做的一个操作就是 移动，否者就不移动；

                        willHitDirection = myTank.willHitInBlockView(direction, it)

                        //这里表示发生的了碰撞；说明我们是不能移动的；
                        if (willHitDirection != null) {
                            return@outside
                        }
                    }
                }
                //这里表示和所有的都不会发生碰撞的一个操作；
                if (willHitDirection == null) {
                    myTank.move(direction)
                }
            }
        */
    }



    /**
     * 刷新的方法；
     */
    override fun onRefresh() {
        println("onRefresh")


        //这里要做的一个操作就是让其自动销毁；
        mAllView.filterAndForEach<DestoryAble> {
            if (it.isNeedDestory()) {
                mAllView.remove(it as View);
            }
        }


        if(isGameOver()){
            mAllView.add(GameOver())
            return
        }

        //这里我们要检查一下是否有发生碰撞:在这里执行表示的意思我们提前判断一下；
        mAllView.filterAndForEach<Moveable> {

            moveableView ->

            run GoToBreak@{

                mAllView.filterAndForEach<Blockable> {

                    if (it != moveableView) {
                        val isWillHit = moveableView.willHitInBlockView(it)
                        if (isWillHit) {
                            //这里表示有冲突了，我们要提示相应的方法；
                            moveableView.notiyHitIndirection(isWillHit);
                            return@GoToBreak
                        }
                    }
                }
            }
        }


        //遍历所有的攻击接口；
        mAllView.filterAndForEach<Attackable> {

            attackableView  ->

            mAllView.filterAndForEach<Sufferable> {

                if(it!=attackableView){

                    var attack = attackableView.attack(it)
                    if(attack){
                        //如果攻击到了，我们要提醒，攻击者和被攻击者
                        //这里视频返回的是一个数组，这里我们返回的是一个View;
                        var blastView = it.notifySufferSucceser(attackableView);
                        if(blastView!=null){
                            mAllView.addAll(blastView)
                        }
                        attackableView.notifyAttactSuccess();
                    }
                }
            }
        }

        //遍历所有自动移动的接口；
        mAllView.filterAndForEach<AutoMovable> {
            it.autoMove()
        }

        //判断自动移动的是否发生了碰撞；
        mAllView.filterAndForEach<AutoMovable> {
            autoMovableView ->

            run GoBack@{

                mAllView.filter {
                    (it is Blockable) && (it !=autoMovableView)
                }.map {
                    it as Blockable
                }.forEach {
                    //这里判断一下，自动移动的是否发生了碰撞；
                    val isWillHit = autoMovableView.willHitInBlockView(it)
                    if (isWillHit) {
                        //这里表示有冲突了，我们要提示相应的方法；
                        autoMovableView.notiyHitIndirection(isWillHit);
                        return@GoBack
                    }
                }
            }
        }

        //敌方坦克自动发射子弹；
        mAllView.filterAndForEach<Enemy> {
            //这里我们要做的一个操作就是发射一颗子弹
            val bullet:Bullet?=it.createBullet();
            bullet?.run {
                mAllView.add(this)
            }
        }


    }

    /**
     * 这里我们是判断一下是否游戏结束的逻辑；
     */
    private fun isGameOver(): Boolean =isLose() || isWin()



    private fun isWin() = mAllView.filter { it is Enemy }.isEmpty()

    private fun isLose(): Boolean{
        var lose = mAllView.filter { it is Camp }.isEmpty()
        var isLose = mAllView.filter { it is MyTank }.isEmpty()
        return lose || isLose
    }
}


